#ifndef RINGBUF_H
#define RINGBUF_H

#include <stdbool.h>

#ifdef __GNUC__
#define smp_wmb __sync_synchronize
#endif

struct ringbuf_t {
    unsigned char *data;
    unsigned int in, out, mask, esize;
};

#ifdef __cplusplus
extern "C" {
#endif

bool init_ringbuf(struct ringbuf_t *self, unsigned int item_size, unsigned int item_count);
void free_ringbuf(struct ringbuf_t *);

// item count in buf
unsigned int ringbuf_len(const struct ringbuf_t *self);

// max item count in buf
unsigned int ringbuf_cap(const struct ringbuf_t *self);

// avail item count
unsigned int ringbuf_avail(const struct ringbuf_t *self);

bool ringbuf_is_full(const struct ringbuf_t *self);
bool ringbuf_is_empty(const struct ringbuf_t *self);

unsigned int ringbuf_in(struct ringbuf_t *self, const void *buf, unsigned int item_count);
unsigned int ringbuf_out(struct ringbuf_t *self, void *buf, unsigned int item_count);
unsigned int ringbuf_out_peek(struct ringbuf_t *self, void *buf, unsigned int len);

#ifdef __cplusplus
} // extern "C"
#endif

#endif // RINGBUF_H
